'''
Created on 2010/08/11

@author: yukiyonezawa
'''
#next implements
from pyrfid.asn1.Encoder import Encoder
from pyrfid.asn1.Decoder import Decoder
from pyrfid.DataProtocol.DSFID.AccessMethod.PackedObjects.IDTable import IDTable
import re
from pyrfid.DataProtocol.DSFID.Processor.Decompactor import Decompactor
import binascii
from pyrfid.Util.Util import Util
import sys
from sre_parse import isdigit
from pyrfid.DataProtocol.AddObject import AddObject

class AuxFormat(object):
    """
    Aux Format is identically defined, whether the Packed Object is an IDLPO or an IDMPO
    """
    
    #these parameter is used for auxformat
    __PACED_OBJECT = "1"
    __APPLICATION_DEFINED = "000"
    __COMPACT_NON_DIRECTORY = "001"
    __COMPACT_NON_DIRECTORY_UTF8 = "010"
    
    __VARIABLE_LEBGTH = list()
    __PREFIX_LENGTH = list()
    __COMPACTION_TYPE = int()
    __COMPACTION_TYPE_IN_APPLICATION = int()
    __EXTENSIBLE_BIT = 4
        
    def __init__(self, application_compaction_type):
        self. __VARIABLE_LEBGTH = list()
        application_compaction_type =  str(application_compaction_type)
        if application_compaction_type == AddObject.PACKE_OBJECT:
            self.__COMPACTION_TYPE = self.__PACED_OBJECT
            self.__COMPACTION_TYPE_IN_APPLICATION = AddObject.PACKE_OBJECT
        elif application_compaction_type == AddObject.COMPACT:#non-directory or directory
            self.__COMPACTION_TYPE = self.__COMPACT_NON_DIRECTORY
            self.__COMPACTION_TYPE_IN_APPLICATION = AddObject.COMPACT
        elif application_compaction_type == AddObject.UTF8_DATA:
            self.__COMPACTION_TYPE_IN_APPLICATION = AddObject.UTF8_DATA
        else:
            raise "ERROR"
    
    @classmethod
    def getCompactionParameterInApplication(cls, binary_bit):
        if binary_bit == cls.__PACED_OBJECT:
            return AddObject.PACKE_OBJECT
        elif binary_bit == cls.__COMPACT_NON_DIRECTORY:
            return AddObject.COMPACT
        elif binary_bit == cls.__APPLICATION_DEFINED:
            return AddObject.APPLICATION_DEFINED
            
    def build(self, defined_packed_objects, changed_order_add_data_set_list):
    
        if self.__COMPACTION_TYPE == self.__PACED_OBJECT:     
            self.__COMPACTION_TYPE = self.__PACED_OBJECT    
            self.__compactPackedObject(defined_packed_objects, changed_order_add_data_set_list)
        elif self.__COMPACTION_TYPE == self.__COMPACT_NON_DIRECTORY:
            self.__compactNonDirectory()
        elif self.__COMPACTION_TYPE == self.__COMPACT_NON_DIRECTORY_UTF8:
            self.__compactNonDirectoryUTF8()
        else:
            pass
                
    def getBit(self):        
        return_bit = self.__COMPACTION_TYPE
        for value in self.__VARIABLE_LEBGTH:
            return_bit += Util.convertExtensibleBitVectorToBit(value, self.__EXTENSIBLE_BIT)
        return return_bit
    
    def getVariableLength(self, index):
        return self.__VARIABLE_LEBGTH[index]
    
    def getCompactionType(self):
        return self.__COMPACTION_TYPE
    
    def getCompactionTypeInApplication(self):
        return self.__COMPACTION_TYPE_IN_APPLICATION
    
    @classmethod
    def analyzeAuxFormat(cls, all_data_bit, object_info, included_idInfo):

        compaction_type = all_data_bit[0]
        if compaction_type != cls.__PACED_OBJECT:
            compaction_type += all_data_bit[1:3]        
        all_data_bit = all_data_bit[len(compaction_type):]
        
        application_compaction_type = AuxFormat.getCompactionParameterInApplication(compaction_type)
        auxformat = AuxFormat(application_compaction_type)
        
        #count varibale-length
        count_varibale = 0
        variable_length_idInfo = list()
        for IDInfo in included_idInfo:
            if IDInfo.isCombinationOID() == True:
                for index, format in enumerate(IDInfo.getSplitedFormatStr()):
                    if "*" not in format:
                        continue
                    variable_length_idInfo.append(IDInfo)              
                    count_varibale += 1
            else:
                if "*" not in IDInfo.getFormatStr():
                    continue
                variable_length_idInfo.append(IDInfo)
                count_varibale += 1
        
        #get prefix       
        for index in range(count_varibale):
            extensible_int = Util.convertExtensibleBitVertorToInt(all_data_bit, cls.__EXTENSIBLE_BIT)
            extensible_bit = Util.convertExtensibleBitVectorToBit(extensible_int, cls.__EXTENSIBLE_BIT)
            all_data_bit = all_data_bit[len(extensible_bit):]
            auxformat.addVariableLength(extensible_int)
        return auxformat, all_data_bit
        
    def __compactPackedObject(self, defined_packed_objects, add_data_set_list):
        #ref AnnexI.7.2
        #3n 1*15n
            
        target_IDInfo_list =  IDTable.useIDTableInfo(defined_packed_objects, add_data_set_list)
        
        for IDInfo in target_IDInfo_list:
            if IDInfo.isCombinationOID() == True:
                for index, format in enumerate(IDInfo.getSplitedFormatStr()):
                    if "*" not in format:
                        continue                    
                    value = ""
                    for data_set in add_data_set_list:
                        if data_set.OBJECT_IDENTIFIER == Encoder.oidEncode(defined_packed_objects.getKRootOID() + " " + IDInfo.getSplitedOIDStringByIndex(index)):
                            value = data_set.OBJECT
                            break                                        
                    self.__calculatePrefix(format, value)
            else:
                if "*" not in IDInfo.getFormatStr():
                    continue
                
                value = ""
                for data_set in add_data_set_list:
                    for oid in IDInfo.getOIDString():
                        if data_set.OBJECT_IDENTIFIER == Encoder.oidEncode(defined_packed_objects.getKRootOID() + " " + oid):
                            value = data_set.OBJECT
                            break
                    if value != "":
                        self.__calculatePrefix(IDInfo.getFormatStr(), value)
                        break
    
    def __calculatePrefix(self, format, value):
        #get prefix
        prefix = 0
        if len(format.split(" ")) >= 2:
            prefix_str_all = format.split(" ")[0]
            prefix_str = ""
            for temp in prefix_str_all:
                if isdigit(temp) == False:
                    break
                prefix_str += temp
            prefix = int(prefix_str)
        print "AUX FORMAT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        print value
        print prefix
        print "END AUX FORMAT++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        self.addVariableLength(len(value) - prefix)

    def addVariableLength(self, variable_length):
            self.__VARIABLE_LEBGTH.append(variable_length)
        
    def __compactNonDirectory(self):
        pass
    
    def __compactNonDirectoryUTF8(self):
        pass 